using System.Transactions;
using AutoMapper;
using DealerPlatform.Common.EventBusHelper;
using DealerPlatform.Common.RedisModule;
using DealerPlatform.Core;
using DealerPlatform.Core.Repository;
using DealerPlatform.Domain;
using DealerPlatform.Service.OrderApp.Dtos;
using Microsoft.EntityFrameworkCore;

namespace DealerPlatform.Service.OrderApp;

public partial class OrderService(
    IRepository<SaleOrderMaster> saleOrderMasterRepository,
    IRepository<SaleOrderDetail> saleOrderDetailRepository,
    IRepository<SaleOrderProgress> saleOrderProgressRepository,
    IRedisWorker redisWorker,
    IMapper mapper,
    LocalEventBus<SaleOrderDto> saleOrderDtoLocalEventBus) : IOrderService
{
    /// <summary>
    ///  获得订单详情
    /// </summary>
    /// <param name="orderNo"></param>
    /// <returns></returns>
    public async Task<SaleOrderDto> GetOrderInfoByOrderNo(string orderNo)
    {
        // 获取主订单
        var orderMaster =
            (await saleOrderMasterRepository.GetListAsync(m => m.SaleOrderNo == orderNo)).FirstOrDefault();
        // 转成Dto
        var saleOrderDto = mapper.Map<SaleOrderDto>(orderMaster);
        // 获取订单流程
        saleOrderDto.OrderProgress = (await GetProgressByOrderNos(saleOrderDto.SaleOrderNo)).FirstOrDefault();
        // 根据主订单获取订单详情
        saleOrderDto.OrderDetails = await GetOrderDetailsByOrderNos(saleOrderDto.SaleOrderNo);
        // 触发总线，获取开票人信息
        await saleOrderDtoLocalEventBus.Publish(saleOrderDto);
        return saleOrderDto;
    }

    public async Task<List<SaleOrderDto>> GetSaleOrders(PageWithSortDto pageWithSortDto)
    {
        pageWithSortDto.Sort ??= "SaleOrderNo";
        var orders = await saleOrderMasterRepository.GetListAsync(pageWithSortDto);
        var orderDtos = orders.Select(o => new SaleOrderDto()
        {
            Id = o.Id,
            SaleOrderNo = o.SaleOrderNo,
            CustomerNo = o.CustomerNo,
            InputDate = o.InputDate
        }).ToList();
        var orderNos = orderDtos.Select(o => o.SaleOrderNo).ToArray();
        var orderDetails = await GetOrderDetailsByOrderNos(orderNos);
        orderDtos.ForEach(o =>
        {
            o.OrderDetails = orderDetails.Where(m => m.SaleOrderNo == o.SaleOrderNo).ToList();
        });

        return orderDtos;
    }

    public async Task<bool> BuyAgain(string saleOrderNo)
    {
        using TransactionScope ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
        try
        {
            var newOrderTime = DateTime.Now;
            var master = await saleOrderMasterRepository.GetAsync(m => m.SaleOrderNo == saleOrderNo);
            var details = await saleOrderDetailRepository.GetListAsync(m => m.SaleOrderNo == saleOrderNo);
            var newSaleOrderNo = Guid.NewGuid().ToString();
            master.SaleOrderNo = newSaleOrderNo;
            master.InputDate = newOrderTime;
            master.DeliveryDate = newOrderTime.AddDays(1);
            await saleOrderMasterRepository.InsertAsync(master);

            details.ForEach(async d =>
            {
                d.SaleOrderNo = newSaleOrderNo;
                d.SaleOrderGuid = Guid.NewGuid().ToString();
                d.InputDate = newOrderTime;
                await saleOrderDetailRepository.InsertAsync(d);
            });

            var progress = new SaleOrderProgress()
            {
                ProgressGuid = Guid.NewGuid().ToString(),
                SaleOrderNo = newSaleOrderNo,
                StepName = "下单",
                StepSn = 1,
                StepTime = newOrderTime
            };
            await saleOrderProgressRepository.InsertAsync(progress);
            ts.Complete();
            return true;
        }
        catch (Exception e)
        {
            ts.Dispose();
            throw;
        }
    }
}